Anshuman Bhat, Product Management Compute Platforms
Jeremy Tanner, Open Source Programs
Andy Terrel, CUDA Python Product
GTC 2025 – March 18, 2025
2006年,NVIDIA发明了CUDA。预计到2026年,CUDA将庆祝其20周年生日。下图展示了从2003年到2006年,CPU和GPU每秒浮点运算性能的增长对比,以及NVIDIA GeForce 8800 (G80)的相关信息,该产品为DirectX 10进行了架构设计。
CUDA是一个分层的开发平台,旨在为开发者和应用程序生态系统提供支持。其核心架构如下图所示,其中Python是受支持的并行语言之一,位于NVIDIA加速库之上,并通过编译器目标(如NVVM/LLVM IR和PTX Assembly ISA)与硬件交互。
NVIDIA致力于将CUDA深度整合到Python生态系统中,以服务于庞大的开发者群体。
- 潜在用户规模:
- 可从GPU中受益的Python开发者:1亿
- 拥有成熟GPU用例的AI与科学计算开发者:3000万
- 已直接使用CUDA的开发者:600万
stack overflow 2024年开发者调查,Python是最受欢迎的编程语言之一。NVIDIA通过多种方式提升CUDA开发者的体验,核心策略围绕社区参与、技术教育和资源可及性。关键举措包括:
- 自适应路线图 (Adaptive Roadmap)
- 社区参与 (Community Engagement)
- GPU资源可及性 (Accessibility to GPUs)
- 现代CUDA教学 (Teach Modern CUDA)
- GTC2025
- 行业活动 (Industry Events)
GPU很早就通过社区主导的开源项目进入了Python生态系统。下图展示了从2010年到2025年主要Python GPU项目的发展历程。
开源社区对在主流Python库中增加GPU/CUDA支持表现出强烈需求。例如,在scikit-image项目的GitHub Issues中,有开发者明确提出为部分函数增加GPU/CUDA支持的计划。
NVIDIA积极参与并支持各类开发者社区活动、编程冲刺(sprints)和研讨会,与开发者共同推动Python生态的GPU加速。
通过与社区的紧密合作,社区的需求正在被实现。例如,针对scikit-image库中增加后端支持的需求,社区成员提交并合并了一个关键的拉取请求(Pull Request),为调度到不同后端(如GPU)提供了基础架构。
NVIDIA与Python生态系统中的多个核心基金会合作,共同促进开源科学计算的发展。
- Python Software Foundation
- NumFOCUS Foundation
- PyTorch Foundation
Anaconda 作为 NVIDIA 的长期 Python 合作伙伴,在其平台中集成了 CUDA。
生态系统规模:
重要发布:
NVIDIA 鼓励社区通过其开源项目进行合作。
NVIDIA 的一项核心任务是:
<blockquote>让 CUDA 在 Python 中的使用容易 100 倍。
</blockquote>"一等公民"意味着 CUDA 现在将 Python 纳入了平台的每一个 API 和特性中,实现了跨不同层次库的互操作性(可混合搭配使用)。
下图展示了 CUDA Python 在整个技术栈中的分布,从底层的运行时和工具,到顶层的框架和领域特定语言(DSLs)。
这是一个具体的科学应用案例,展示了研究人员如何利用 GPU 加速其工作流程。
数组编程是科学计算的基础。NumPy 是 Python 中数组编程的核心库,它允许高效地创建和操作多维数组。
NumPy 数组是构建更高级领域特定库的基石,这些库广泛应用于数据科学和机器学习,例如 PyTorch, JAX, scikit-learn, biopython 等。
为了解决不同数组库之间的兼容性问题,Python 社区制定了 Python 数组 API 标准,并得到了广泛采用。这促进了生态系统中不同库之间的互操作性。
为了利用 GPU 的并行计算能力,可以将基于 CPU 的 NumPy 工作流无缝迁移到 GPU。CuPy 是一个实现了与 NumPy 兼容 API 的库,使得这种迁移变得简单。
DLPack 是一种开放的内存张量结构标准,用于在不同深度学习框架之间实现零拷贝的数据交换。它定义了一套通用的数据结构,如 DLTensor 和 DLDevice,使得数据可以在支持该标准的框架(如 PyTorch, TensorFlow, CuPy, MXNet 等)之间高效传递,无需在设备内存之间进行昂贵的数据复制。
下图展示了 DLPack 的核心数据结构。
从 NumPy 到 CuPy,再到 nvmath-python,展示了向优化 GPU 库演进的路径。
一个通往高性能 GPU 库的 Pythonic 接口
下图对比了无状态和有状态 API 在执行快速傅里叶变换(FFT)时的代码差异。有状态 API 通过预先创建并规划 FFT 对象,在多次执行中分摊了规划成本,而无状态 API 在每次调用时都进行规划。
PHROSTY 超新星发现与光度测量流水线
该应用程序包含3个部分:
1. 预处理(Preprocessing):涉及计算点扩散函数(point-spread function)。
2. sFFT:将图像转换到傅里叶空间,并进行图像相减。
3. 后处理(Postprocessing):寻找并应用去相关函数。
PHROSTY 增量加速
下图展示了通过利用支持 GPU 的 Python 库所实现的性能提升。与使用 NumPy 在 CPU 上运行相比,使用 CuPy 在 GPU 上(未优化)可获得 23倍 的加速,而结合使用 CuPy 和 nvmath-python 的优化 GPU 版本则可实现 39倍 的加速。
这是一个与杜克大学、匹兹堡大学、卡内基梅隆大学和劳伦斯伯克利国家实验室的合作研究项目。
SLAC 的直线加速器相干光源 (LINAC coherent light source)
该研究由 SLAC 国家加速器实验室的副研究员 Quynh Nguyen 博士领导。实验通过激光激发材料,然后使用 X 射线(5-20 keV)进行探测,这个过程会产生太字节(Terabytes)级别的数据。
软件栈的演进路径从 NumPy 开始,通过 CuPy 迁移到 GPU。为了进一步扩展到超级计算机,可以采用两种并行策略:
- 显式并行(Explicit Parallelism):使用通信库,如 mpi4py 和 nvshmem4py。
- 隐式并行(Implicit Parallelism):使用领域特定库,如 cuPyNumeric。
cuPyNumeric 能够以零代码更改的方式实现扩展,从单 CPU 扩展到 GPU,乃至多 GPU 和多节点集群。用户只需将代码中的 import numpy as np 更改为 import cupynumeric as np 即可。
Legate 是 cuPyNumeric 背后的运行时系统。
- 轻松扩展的隐式并行提取:库将 API 调用转换为任务,运行时通过依赖性分析来提取并行性。
- 用于可组合性的统一数据抽象:Legate 运行时为不同的数据结构(如 np.ndarray, sparse.csr_matrix, pd.DataFrame)提供统一的数据存储抽象,增强了不同库之间的组合性。
下图展示了使用 NumPy 和 cuPyNumeric 在进行实验、数据分析、决策和最终发现过程中的时间对比。
- NumPy: 整个过程耗时约 3年,其中绝大部分时间用于数据分析。
- cuPyNumeric: 整个过程缩短至 小于5分钟。
如今的 JAX 和 PyTorch 等框架深度运行在 CUDA C++ 之上。下图展示了从高层框架(如 PyTorch)到底层硬件驱动的完整软件栈,突出了 cuDNN、cuBLAS、CUTLASS 和 CUDA C++ 等关键组件在其中的作用。
展示了 PyTorch 通过 Lightning AI 创建的 Lightning Thunder 编译器,最终调用 cuDNN 库的流程。这使得高层框架能够利用如 Flash Attention 等底层优化核,来进行高效的推理和训练。
与 Python 时代保持同步
传统 Python 由于全局解释器锁(GIL)的存在,多线程无法实现真正的并行执行。自由线程(Free Threading)旨在移除 GIL,允许多个线程同时执行,从而实现真正的并行计算。
通过使用线程,可以实现 CUDA 上下文共享、降低内存消耗并利用线程级并行。下图比较了在图像解码(使用 NVImageCodec)任务中,使用多进程与多线程的吞吐量。结果显示,使用线程可以获得显著更高的吞吐量(例如,9个线程时达到 736k imgs/sec)。
提供了一个处理了所有依赖关系的 Docker 镜像,以支持自由线程的 PyTorch 环境。下图展示了其复杂的依赖关系图。
将科学原理应用于模拟,可以解决复杂问题。以下是一些模拟应用的示例:
这些模拟涵盖了多个领域:
- 纳维-斯托克斯(Navier-Stokes)流体模拟:模拟流体绕过障碍物的行为。
- 混合欧拉-拉格朗日(Hybrid Eulerian-Lagrangian)流体:模拟复杂的流体效果。
- 新胡克(Neo-Hookean)弹性:模拟弹性材料的形变。
- 机器人任务:使用 warp.fem 进行机器人与环境的交互模拟。
NVIDIA Warp 为模拟和AI提供了强大的功能,主要分为三个方面:
几何处理 (Geometry Processing)
可微分模拟 (Differentiable Simulation)
加速模型与训练 (Accelerated Models and Training)
Warp 是一个为 Python 设计的可微分空间计算库,使得在 Python 中编写高性能 CUDA 内核变得简单。
pip install warp-lang@wp.kernel 装饰器定义,并使用 wp.launch 在 CUDA 设备上启动。import warp as wp
@wp.kernel
def integrate(p: wp.array(dtype=wp.vec3),
v: wp.array(dtype=wp.vec3),
f: wp.array(dtype=wp.vec3),
m: wp.array(dtype=float)):
tid = wp.tid()
# Semi-implicit Euler step
v[tid] = v[tid] + f[tid] * m[tid] * dt
wp.vec3(0.0, -9.8, 0.0) * dt
x[tid] = x[tid] + v[tid] * dt
# kernel launch
wp.launch(integrate, dim=1024, inputs=[x, v, f, ...], device="cuda:0")
硬件和编程模型的演进,正从传统的基于单个线程的编程模式,转向更高效、更抽象的基于数组(张量)的编程模式。这一转变为 Tensor Core 的高效利用奠定了基础。
cuTile 使得基于数组/张量的编程在 Python 中更加自然。
下图对比了使用 NumPy 和 cuTile 实现 Softmax 的代码。cuTile 的代码结构与 NumPy 类似,但能直接在 GPU 上高效执行。Tileblocks 并行加载和计算各自的数据块。
通过对比矩阵乘法算法的实现,可以清晰地看到 Tile 编程的优势。与使用 Numba SIMT 编写的复杂底层 CUDA C++ 风格代码相比,cuTile-python 的实现更加简洁、高级。
cuTile 可用于在 PyTorch 中通过自定义核函数实现 Llama-3.1 的推理。性能测试表明,在 Blackwell B200 平台上,cuTile 的性能可以达到 PyTorch Eager 模式下使用 cuDNN SDP 优化后性能的 93%,展现了其强大的性能潜力。
cuTile 实现了在 Python 中以更少的代码、更短的实现时间,获得接近于手动调优 C++ 的性能。
我们提供了一系列学习路径,帮助您掌握 CUDA Python:
第 0 步: 了解我们的 Python 故事
第 1 步: 学习 CUDA Python 工具
第 2 步: 深入内核
第 3 步: 精通 Tensor Core
GTC 2025 提供了丰富的 CUDA 相关会议,涵盖从入门到精通的各个层面:
更多详情请访问:http://nvidia.com/gtc/sessions/cuda-developer
此幻灯片为NVIDIA的品牌过渡页,不包含具体的技术或学术内容。